package com.weiqiao.api.until.service.impl;

import com.weiqiao.api.domain.vo.redis.RedisApiVo;
import com.weiqiao.api.until.service.RedisApiService;
import com.weiqiao.utils.PageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Zheng Jie
 * @date 2018-12-10
 */
@Service("RedisApiServiceImpl")
public class RedisApiServiceImpl implements RedisApiService {

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public void customSave(String key, Object val, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key,val,1, TimeUnit.DAYS);
    }

    @Override
    public String getCustomSaveVal(String key) {
        try {
            String value = redisTemplate.opsForValue().get(key).toString();
            return value;
        }catch (Exception e){
            return "";
        }
    }

    @Override
    public Page<RedisApiVo> findByKey(String key, Pageable pageable){
        List<RedisApiVo> redisVos = new ArrayList<>();
        if(!key.equals("*")){
            key = "*" + key + "*";
        }
        for (Object s : redisTemplate.keys(key)) {
            // 过滤掉权限的缓存
            if (s.toString().indexOf("role::loadPermissionByUser") != -1 || s.toString().indexOf("user::loadUserByUsername") != -1) {
                continue;
            }
            RedisApiVo redisVo = new RedisApiVo(s.toString(),redisTemplate.opsForValue().get(s.toString()).toString());
            redisVos.add(redisVo);
        }
        Page<RedisApiVo> page = new PageImpl<RedisApiVo>(
                PageUtil.toPage(pageable.getPageNumber(),pageable.getPageSize(),redisVos),
                pageable,
                redisVos.size());
        return page;
    }



    @Override
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    @Override
    public void flushdb() {
        redisTemplate.getConnectionFactory().getConnection().flushDb();
    }

    @Override
    public String getCodeVal(String key) {
        try {
            String value = redisTemplate.opsForValue().get(key).toString();
            return value;
        }catch (Exception e){
            return "";
        }
    }

    @Override
    public void saveCode(String key, Object val) {
        redisTemplate.opsForValue().set(key,val,2000);
    }
    
    @Override
    public void set(String key, Object val) {
        redisTemplate.opsForValue().set(key,val);
    }
    
    @Override
    public String get(String key) {
        try {
            String value = redisTemplate.opsForValue().get(key).toString();
            return value;
        }catch (Exception e){
            return "";
        }
    }
    
    @Override
    public void hset(String key, String hashKey, Object val) {
        redisTemplate.opsForHash().put(key, hashKey, val);
    }
    
    @Override
    public String hget(String key, String hashKey) {
        try {
            String value = redisTemplate.opsForHash().get(key, hashKey).toString();
            return value;
        }catch (Exception e){
            return "";
        }
    }

    // TimeUnit.DAYS          //天
    // TimeUnit.HOURS         //小时
    // TimeUnit.MINUTES       //分钟
    // TimeUnit.SECONDS       //秒
    // TimeUnit.MILLISECONDS  //毫秒
    // TimeUnit.NANOSECONDS   //毫微秒
    // TimeUnit.MICROSECONDS  //微秒
    @Override
    public void hsetForDate(String key, String hashKey, Object val, int outdate) {

        redisTemplate.opsForHash().put(key, hashKey, val);
        redisTemplate.expire(key,outdate, TimeUnit.SECONDS);
    }
    
    @Override
    public Map hgetAll(String key) {
        try {
        	Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
            return entries;
        }catch (Exception e){
            return null;
        }
    }
    
    @Override
    public void hdelete(String key, String hashKey) {
    	redisTemplate.opsForHash().delete(key, hashKey);
    }

    @Override
    public long lGetListSize(String key){
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public boolean exist(String key) {
        redisTemplate.hasKey(key);
        return false;
    }

    @Override
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public boolean rPush(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean lPush(String key, Object value) {
        try {
            redisTemplate.opsForList().leftPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean rPop(String key) {
        try {
            redisTemplate.opsForList().rightPop(key);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean lPop(String key) {
        try {
            redisTemplate.opsForList().leftPop(key);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean rPushAll(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean lPushAll(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().leftPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}
